package api

import (
	"errors"
	beego "github.com/beego/beego/v2/adapter"
	"github.com/dgrijalva/jwt-go"
	"strconv"
	"strings"
	"weiboxs.com/new_h_glasses/enums"
	"weiboxs.com/new_h_glasses/models"
)

const jwtKey = "jwt_new_h_glasses"

type ApiBaseController struct {
	beego.Controller
	curUser models.BackendUser //当前用户信息
}

//设置接口握手
func (c *ApiBaseController) Handshake() {
	c.jsonResult(enums.JRCodeSucc, "ok", "")
}

func (c *ApiBaseController) jsonResult(code enums.JsonResultCode, msg string, data interface{}) {
	c.Data["json"] = &models.JsonResult{code, msg, data}
	c.ServeJSON()
	c.StopRun()
}

type JsonResultData struct {
	Code  enums.JsonResultCode `json:"code"`
	Count int64                `json:"count"`
	Data  interface{}          `json:"data"`
}

func (c *ApiBaseController) jsonResultData(code enums.JsonResultCode, count int64, data interface{}) {
	c.Data["json"] = &JsonResultData{code, count, data}
	c.ServeJSON()
	c.StopRun()
}

func (c *ApiBaseController) parseToken() (t *jwt.Token, e error) {
	authString := c.Ctx.Input.Header("Authorization")

	kv := strings.Split(authString, " ")
	if len(kv) != 2 || kv[0] != "Bearer" {
		return nil, errors.New("TOKEN验证失败：" + authString)
	}
	tokenString := kv[1]

	// Parse token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte(jwtKey), nil
	})
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				// That's not even a token
				return nil, errors.New("不是有效的TOKEN")
			} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
				return nil, errors.New("TOKEN已过期")
			} else {
				return nil, errors.New("无法处理TOKEN")
			}
		} else {
			// Couldn't handle this token
			return nil, errors.New("无法处理TOKEN")
		}
	}
	if !token.Valid {
		return nil, errors.New("TOKEN验证失败：" + authString)
	}
	return token, nil
}

func (c *ApiBaseController) CtrLoginToken() {
	token, e := c.parseToken()
	if e != nil {
		c.jsonResult(enums.JRCodeFailed, e.Error(), "nologin")
		return
	}

	claims, ok := token.Claims.(jwt.MapClaims)
	if !ok {
		c.jsonResult(enums.JRCodeFailed, "获取用户信息失败", "nologin")
		return
	}
	user := models.BackendUser{}
	user.Id, _ = strconv.Atoi(claims["uid"].(string))
	user.UserName = claims["username"].(string)
	user.RealName = claims["realname"].(string)
	user.DepartmentId, _ = strconv.ParseInt(claims["departmentid"].(string), 0, 64)
	user.Mobile = claims["mobile"].(string)
	c.curUser = user
	models.CurLoginUserInfo = c.curUser

}

// 判断某 Controller.Action 当前用户是否有权访问
func (c *ApiBaseController) checkActionAuthor(authName string) bool {
	if c.curUser.Id == 0 {
		return false
	}
	v := c.curUser
	//如果是超级管理员，则直接通过
	if v.IsSuper == true {
		return true
	}
	resourceList := models.ResourceTreeGridByUserId(v.Id, 1000)
	//遍历用户所负责的资源列表
	for i, _ := range resourceList {
		urlfor := strings.TrimSpace(resourceList[i].UrlFor)
		if len(urlfor) == 0 {
			continue
		}
		strs := strings.Split(urlfor, ",")
		if len(strs) > 0 && strs[0] == authName {
			return true
		}
	}

	return false
}
//验证权限
func(c *ApiBaseController) checkAuthor(authName string) {
	c.CtrLoginToken() //判断登录

	if c.checkActionAuthor(authName) == false {
		c.jsonResult(enums.JRCodeFailed, "没有操作权限", "")
	}
}